package com.CMUBiS.PageControllers;

import com.CMUBiS.util.Image;
import java.util.ArrayList;
import java.util.Calendar;

import javax.servlet.http.HttpServletRequest;

import com.CMUBiS.Data.Error;
import com.CMUBiS.Data.GlobalErrors;
import com.CMUBiS.Data.GlobalVars;
import com.CMUBiS.util.CheckInputs;
import com.CMUBiS.util.Item;
import com.CMUBiS.util.StopWatch;

/**
 * This is a blank example of a page controller. You can copy and edit it to make new pages
 * 
 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
 * @version 0.1
 * @since 0.1
 * @date 04/05/2011
 */

public class ViewItemController extends PageController{
	// Variables passed in the request
	private int userID = -1;
	private String authToken = null;
	private int itemID;
	private float bid = 0.0f;
	private float maxBid = 0.0f;
	private int quantity = 1;
	
	// Structures to hold the DB data
	private Item item = null;
	
	// Structures to hold the parsed page data
	private String redirectURL = null;
	private boolean isOld = false;
	private boolean canBuyNow = false;
	private String thumbnailURL = null;
	private String[] imageURLs = null;
	private String reserveMet = null;
	
	/**
	 * This method checks the page for any input errors that may have come from Client generator error
	 * These would need to be check in real life to stop users attempting to hack and mess with things
	 * 
	 * @param request
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void checkInputs(HttpServletRequest request){
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		if(request != null){
			super.checkInputs(request);
			
			// Get the userID (if exists), we will pass it along to the next pages
			try{
				this.userID = CheckInputs.checkUserID(request);
			}
			catch(Error e){	}
			
			// Get the authToken (if exists), we will pass it along to the next pages
			try{
				this.authToken = CheckInputs.checkAuthToken(request);
			}
			catch(Error e){	}
			
			// Get the itemID 
			try{
				this.itemID = CheckInputs.checkItemID(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.itemID = -1;
			}
			
			// Get the bid amount
			try{
				this.bid = CheckInputs.checkBid(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.bid = 0.0f;
			}
			
			// Get the max bid amount
			try{
				this.maxBid = CheckInputs.checkMaxBid(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.maxBid = this.bid;
			}
			
			// Get the quantity
			try{
				this.quantity = CheckInputs.checkQuantity(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.quantity = 1;
			}
			
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalGetParamTime += timer.getTimeTaken();
		}
	}

	/**
	 * This method get the data needed for the HTML4 page from the database
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void getHTML4Data() {	
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		//TODO: make SQL method to get item with images
		
		// Get the item from the database
		if(this.item == null && this.itemID > 0)
			this.item = GlobalVars.db.getItem(itemID, Boolean.TRUE);
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalDBtime += timer.getTimeTaken();
		}
	}

	/**
	 * This method processes all of the data that was read from the database such that it is ready to be printed
	 * on to the page. We try to do as much of the page logic here as possible
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void processHTML4() {
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		if(this.item != null){
			// See if the item is an old item
			if(item.getEndDate().before(Calendar.getInstance().getTime()))
				this.isOld = true;
			
			if(item.getBuyNowPrice() > 0.0f)
				this.canBuyNow = true;
			
			String thumb = item.getThumbnail();
			if(thumb != null && !thumb.equals(EMPTY)){
				this.thumbnailURL = "<img scr=\"" + thumb + "\" heigth=\"40\" width=\"40\" alt=\"" + this.item.getName() +"\">";
			}
			
			if(this.item.getImages() != null){
				ArrayList<Image> images = this.item.getImages();
				int length = images.size();
				
				this.imageURLs = new String[length];
				
				for(int i=0; i<length; i++){
					Image image = images.get(i);
					this.imageURLs[i] = "<img scr=\"" + image.getUrl() + "\" heigth=\"40\" width=\"40\" alt=\"" + image.getDescription() +"\">";
				}
			}
			
			if(this.item.getBuyNowPrice() > this.item.getReservePrice())
				this.reserveMet = "The reserve has been met";
			else
				this.reserveMet = "The reserve price has NOT been met";
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalProcessingTime += timer.getTimeTaken();
		}
	}
	
	/**
	 * Gets the HTML5 data from the database
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void getHTML5Data(){
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalDBtime += timer.getTimeTaken();
		}
	}
	
	/**
	 * Processes the HTML5 data that is needed to create the page
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void processHTML5(){
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalProcessingTime += timer.getTimeTaken();
		}
	}
	/**
	 * Attempts to submit the bid to the database. Adds errors to the Error list if there is problems
	 * 
	 * @return
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public boolean submitBid(){
		// Only if we think the bid might get accepted
		if(this.errors.size() == 0){
			// If the max bid is less than the bid we cannot send
			if(this.maxBid < this.bid){
				if(!errors.contains(GlobalErrors.bidGreaterThanMaxBid))
					errors.add(GlobalErrors.bidGreaterThanMaxBid);
			}
			// We need to hit the database and get the items details for the other checks
			
			if(this.item == null)
				this.item = GlobalVars.db.getItem(itemID, Boolean.TRUE);
				
			// Check that the item is really there
			if(this.item == null){
				if(!errors.contains(GlobalErrors.bidInvalidItem))
					errors.add(GlobalErrors.bidInvalidItem);
				}
			
			// Check that the bid amount is more than the current bid
			if(this.bid <= item.getCurrentBid()){
				if(!errors.contains(GlobalErrors.bidLessThanCurrent))
					errors.add(GlobalErrors.bidLessThanCurrent);
				}
			
			// Check that the item is still running
			if(this.isOld || item.getEndDate().before(Calendar.getInstance().getTime())){
				if(!errors.contains(GlobalErrors.bidOnFinishedAuction))
					errors.add(GlobalErrors.bidOnFinishedAuction);
			}
				
			// Everything okay, so let the DB insert
			else if(this.errors.size() == 0){
				GlobalVars.db.insertBid(userID, itemID, quantity, bid, maxBid);
				createRedirectURL();
				return true;
			}
		}
		
		return false;
	}
	
	/**
	 * If we successfully insert the bid then we'll need to forward them on to the next page.
	 * We'll create the URL here
	 * 	
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	private void createRedirectURL(){
		this.redirectURL = "./confirmbid?userID=" + this.userID + "&authToken=" + this.authToken +"&itemName=" + this.item.getName() + "&bid=" + this.bid;
	}
	
	/**
	 * Returns the current userID as a String
	 * 
	 * @return String the userID
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public String getUserIDString(){
		return Integer.toString(this.userID);
	}
	
	/**
	 * Returns the authToken sent to the page
	 * 
	 * @return string the authToken
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public String getAuthTokenString(){
		return this.authToken;
	}
	
	/**
	 * Returns the URL to be redirected to if the user successfully bids
	 * 
	 * @return String the next URL to redirect to
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public String getRedirectURL(){
		return this.redirectURL;
	}
	
	/**
	 * Returns the item that the user is bidding for
	 * 
	 * @return Item that the user is bidding for
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public Item getItem(){
		return this.item;
	}
	
	public float getBid(){
		return this.bid;
	}
	
	public float getMaxBid(){
		return this.maxBid;
	}
	
	public int getQuantity(){
		return this.quantity;
	}
	
	public boolean getIsOld(){
		return this.isOld;
	}
	
	public boolean getCanBuyNow(){
		return this.canBuyNow;
	}
	
	public String getThumbnailURL(){
		return this.thumbnailURL;
	}
	
	public String[] getImageURLs(){
		return this.imageURLs;
	}
	
	public String reserveMet(){
		return this.reserveMet;
	}
}
